/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import Cart.Cart;
import Cart.DiscountManager;
import Cart.ISearchManager;
import Cart.SearchManager;
import Customer.CustomerManager;
import Customer.ICustomerManager;
import DAO.DAO;
import DTO.*;
import DTO.Order;
import DesktopGUIpackage.mainFrame;
import EmailService.EmailSender;
import Exception.KwickKioskDBException;
import Order.IOrderManager;
import Order.OrderManager;
import Session.SessionManager;
import Utilities.EmailTemplates;
import java.awt.Container;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Rajeeb Saha
 */
public class DesktopController {

    private mainFrame frame;
    private Container pane;
    private DAO dao;
    private ICustomerManager customerManager;
    private IOrderManager orderManager;
    private ISearchManager searchMgr = null;
    private SessionManager sessionMgr;
    private DiscountManager discountMgr = null;
    private DesktopControllerHelper desktopControllerHelper;
    private boolean loggedIn = false;
    private String message;
    private String upc = "";
    private Item item;
    private static final Logger log = Logger.getLogger(DesktopController.class.getName());

    /**
     *
     */
    public DesktopController(DesktopControllerHelper helper) throws KwickKioskDBException {

            getDao();
            sessionMgr = new SessionManager(dao);
            customerManager = new CustomerManager(dao);
            discountMgr = new DiscountManager(dao);
            searchMgr = new SearchManager(dao);
            orderManager = new OrderManager(dao);
            desktopControllerHelper = helper;
            sessionMgr.searchByUPC(upc);

    }

    public void getDao(){
        FileInputStream fstream = null;
        try {
            String location = System.getProperty("user.dir");
            fstream = new FileInputStream(location + "/DatabaseConfig.txt");
            // Get the object of DataInputStream
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            strLine = br.readLine();
            StringTokenizer token = new StringTokenizer(strLine);
            token.nextToken();
            String userName = token.nextToken();
            strLine = br.readLine();
            token = new StringTokenizer(strLine);
            token.nextToken();
            String password = token.nextToken();
            strLine = br.readLine();
            token = new StringTokenizer(strLine);
            token.nextToken();
            String serverName = token.nextToken();
            try {
                dao = new DAO(userName, password, serverName);
            } catch (KwickKioskDBException ex) {
                //NEED TO IMPLEMENT ERROR HANDLING
                Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (IOException ex) {
            Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fstream.close();
            } catch (IOException ex) {
                Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /* FUNCTIONALITY **********************************************************/

    public final void getConnection(){
        getDao();
    }


    public boolean reconnect() {
        getConnection();
        if (dao == null)
            return false;
        sessionMgr = new SessionManager(dao);

        return true;
    }
    /**
     *
     * @param customer
     * @return
     */
    public String registerCustomer(Customer customer) {

        String custId = customerManager.registerCustomer(customer);

        return custId;
    }

    /**
     *
     * @param addressVO
     * @return
     */
    public String addAddress(Address addressVO) {
        return customerManager.addCustomerAddress(
                sessionMgr.getCustomer().getStoreCardNumber(), addressVO);
    }

    public String editAddress(Address addressVO){
        return customerManager.editCustomerAddress(addressVO);
    }

    public void addItemToCart(Item item, int quantity){
        try {
            sessionMgr.addItemToCart(item, quantity);
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            desktopControllerHelper.DatabaseDownScreen();
        }
        desktopControllerHelper.refresh();
    }

    /**
     *
     * @param customerID
     * @param password
     * @return
     */
    public boolean LogIn(String customerID, String password) {

        loggedIn = customerManager.login(Integer.valueOf(customerID), password);
        if (loggedIn) {
            sessionMgr.setCutomerId(Integer.parseInt(customerID));
            sessionMgr.setLoggedIn(loggedIn);
            try {
                sessionMgr.setCustomer(customerID);
            } catch (KwickKioskDBException ex) {
                Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
                desktopControllerHelper.DatabaseDownScreen();
            }

        }
        return loggedIn;
    }

    public void logout(){
        try {
            sessionMgr.logout();
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            desktopControllerHelper.DatabaseDownScreen();
        }
        desktopControllerHelper.changeFrame(1);
    }

    public void clearSession(){
        try {
            sessionMgr.clearSession();
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            desktopControllerHelper.DatabaseDownScreen();
        }
    }

    public String editPersonalInformation(Customer customerVO) {
        return customerManager.editCustomerInfo(customerVO);

    }

    public ArrayList<Order> getOrderHistory(int csid) {
        ArrayList<Order> orders = new ArrayList<Order>();
        orders = (ArrayList<Order>) orderManager.getOrderHistory(csid).clone();
        System.out.println("cust order his" + orders.size());
        return orders;
    }

    public List<Item> getItemHistory(Integer oid) {
        List<Item> items = new ArrayList<Item>();
        System.out.println(" order id selected is " + oid);
        items = orderManager.getItemHistory(oid);
        return items;
    }

    public Customer getCustomerInfo(Integer csid) {
        Customer cust = new Customer();
        int custid = csid.intValue();
        System.out.println("id from screen " + custid);
        if (custid == 0) {
            System.out.println("id from screen " + custid);
            custid = sessionMgr.getCutomerId();
            System.out.println("id from session  " + custid);
        }
        System.out.println("id from session  " + custid);
        try {
            cust = customerManager.getCustomerInfo(custid);
        } catch (Exception ex) {
            log.log(Level.SEVERE, null, ex);
        }
        return cust;
    }

    public List<Category> getCategories() {

        return searchMgr.getCategories();
    }

    public void searchByCategory(Integer ctid) {
        try {
            sessionMgr.searchByCategory(ctid);
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            desktopControllerHelper.DatabaseDownScreen();
        }

    }

    public void searchByKeyword(String keyword, String criteria) {
        try {
            sessionMgr.searchByKeyword(keyword, criteria);
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(DesktopController.class.getName()).log(Level.SEVERE, null, ex);
            desktopControllerHelper.DatabaseDownScreen();
        }

    }

    public Item searchByUPC(String upc) {

        Item newItem = null;
        Item discountedItem = null;

        try {
            newItem = dao.searchByUPC(upc, "WebStore");
            discountedItem = discountMgr.checkDiscountOnItem(newItem);
            List<Item> discountOnCart = this.getSessionMgr().getListDiscountCart();
            if(discountOnCart != null){
                discountOnCart.add(discountedItem);
                this.getSessionMgr().setListDiscountCart(discountOnCart);
            }           
        } catch (KwickKioskDBException ex) {
            System.out.println("Please implement proper error handling for this");
            Logger.getLogger(Cart.class.getName()).log(Level.SEVERE, null, ex);
        }
        return newItem;
    }

    public ArrayList<Address> getShippingAddresses() {

        ArrayList<Address> addressList = new ArrayList<Address>();
        int custId = this.getSessionMgr().getCutomerId();
        addressList = customerManager.getAddressList(custId);
        return addressList;
    }

    public ArrayList<ShippingMethod> getShippingMethods(String province) {
        ArrayList<ShippingMethod> shipmethd = new ArrayList<ShippingMethod>();
        //int custId = this.getSessionMgr().getCutomerId();
        shipmethd = customerManager.getShipMethods(province);
        System.out.println("shipmthd in DesktopController:");
        System.out.println(shipmethd);
        return shipmethd;
    }

    public Integer makeDesktopOrder(Order order) {
        return orderManager.makeDesktopOrder(order);
    }

    public List<Address> getCustomerAddresses(Integer custId) {
        List<Address> addressList = customerManager.getAddressList(custId);
        return addressList;

    }

    public Boolean deleteCustomerAddress(Integer custId, Integer addId) {

        Boolean addDel = false;
        addDel = customerManager.removeCustomerAddress(custId, addId);
        return addDel;

    }

    public void makePayment(Payment pymnt){
        sessionMgr.addPayment(pymnt);
        if(sessionMgr.fullfillDesktopOrder()){
            //email receipt
            emailReceipt();
            //display success screen
            desktopControllerHelper.orderConfirmScreen();
            sessionMgr.setOnPathToPurchase(false);
            System.out.println("order succeeded");
            desktopControllerHelper.refresh();
        }
        else{
            //order failed.
            desktopControllerHelper.orderFailedScreen();
        }
        
    }

    private void emailReceipt(){
        System.out.println("second check passes");
        Integer customerId = sessionMgr.getCutomerId();
        Customer customer = sessionMgr.getCustomer();
        String email = customer.getEmail();
        String[] emails = {email};
        Email emailVo = new Email();
        emailVo.setTo(emails);
        emailVo.setFrom(EmailTemplates.adminEmail);
        emailVo.setEmailSubjectTxt(EmailTemplates.emailSubjectOrderConfirmation);
        emailVo.setEmailMsgTxt(EmailTemplates.emailBodyOrderConfirmation + sessionMgr.getOrder().getId());
        try {
            EmailSender.sendEmail(emailVo);
        } catch (Exception ex) {
            Logger.getLogger(Cart.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    // GETTERS AND SETTERS ----------------------------------------------------//
    /**
     * @return the sessionMgr
     */
    public SessionManager getSessionMgr() {
        return sessionMgr;
    }


    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(String message) {
        this.message = message;
    }
}
